home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
CD ROM Paradise Collection 4
/
CD ROM Paradise Collection 4 1995 Nov.iso
/
graphics
/
font3d10.zip
/
font3d.cpp
< prev
next >
Wrap
C/C++ Source or Header
|
1994-09-15
|
12KB
|
416 lines
//=================================================================================================
// Font3D.CPP
//-------------------------------------------------------------------------------------------------
//
// Copyright (c) 1994 by Todd A. Prater
// All rights reserved.
//
//-------------------------------------------------------------------------------------------------
#include <iostream.h>
#include <fstream.h>
#include <stdio.h>
#include <string.h>
#include "List.H"
#include "Geometry.H"
#include "TrueType.H"
#include "Build.H"
#define FORMAT_POV 0
#define FORMAT_RAW 1
#define PI 3.1415926536
#define NONE 0
#define BEVELED 1
#define SMOOTH 2
void OutputTriangle(ofstream& outputfile, int format, TRIANGLE& t)
{
switch(format)
{
case FORMAT_POV:
outputfile<<"triangle{"
<<"<"<<t.v1.x<<","<<t.v1.y<<","<<t.v1.z<<">,"
<<"<"<<t.v2.x<<","<<t.v2.y<<","<<t.v2.z<<">,"
<<"<"<<t.v3.x<<","<<t.v3.y<<","<<t.v3.z<<">}"<<endl;
break;
}
}
void PrintGreeting(void)
{
cout<<"---------------------------------------"<<endl;
cout<<"Font3D Version 0.50"<<endl;
cout<<"Object Creation Utility "<<endl;
cout<<"Written by Todd A. Prater "<<endl;
cout<<"---------------------------------------"<<endl;
}
void PrintOptions(void)
{
cout<<endl;
cout<<" Command Line Switches:"<<endl;
cout<<endl;
cout<<" /ifilename TrueType Font File to use."<<endl;
cout<<" /ofilename Output File to be later included in a scene "<<endl;
cout<<" description file."<<endl;
cout<<" /nstring Name of the object to generate (POV formats only)."<<endl;
cout<<" /cnnn ASCII Character Code of the letter to generate"<<endl;
cout<<" /rnnn Curve resolution."<<endl;
cout<<" /dfloat Depth of the generated object."<<endl;
cout<<" /fr Output RAW triangles."<<endl;
cout<<" /fs Output POV smooth_triangles."<<endl;
cout<<" /tnnn Angle threshold for smooth triangle output."<<endl;
cout<<endl;
}
void OutputGlyph(ofstream& outputfile,
TTFont& font,
CHARPTR objName,
USHORT code,
USHORT format,
USHORT resolution,
double frontDepth,
double backDepth,
double edgeShrinkFactor,
double faceShrinkFactor,
DOUBLE angleThreshold )
{
int j;
SHORT upem;
DOUBLE xmin,ymin,xmax,ymax;
LIST<TRIANGLE> faceTriList;
LIST<TRIANGLE> edgeTriList;
LIST<TRIANGLE> bevelTriList;
cout<<"Triangulating Face...";cout.flush();
TriangulateFace(font,font.CharacterMap(code),
resolution,faceShrinkFactor,faceTriList);
cout<<"Done."<<endl;
cout<<"Triangulating Edges...";cout.flush();
TriangulateEdges(font,
font.CharacterMap(code),
resolution,
frontDepth-edgeShrinkFactor,
backDepth+edgeShrinkFactor,
angleThreshold,
edgeTriList);
cout<<"Done."<<endl;
/*
if (effects==BEVELED)
{
cout<<"Triangulating Bevels...";cout.flush();
TriangulateBevels(font,code,
resolution,
frontDepth,backDepth,
faceShrinkFactor,edgeShrinkFactor,
bevelTriList);
cout<<"Done."<<endl;
}
*/
cout<<"Writing Output...";cout.flush();
if (format==POV_SMOOTH || format==POV_FLAT)
{
upem = font.UnitsPerEm();
xmin = (DOUBLE)font.GlyphXMin(font.CharacterMap(code))/(DOUBLE)upem;
ymin = (DOUBLE)font.GlyphYMin(font.CharacterMap(code))/(DOUBLE)upem;
xmax = (DOUBLE)font.GlyphXMax(font.CharacterMap(code))/(DOUBLE)upem;
ymax = (DOUBLE)font.GlyphYMax(font.CharacterMap(code))/(DOUBLE)upem;
if (objName==NULL)
{
outputfile<<"#declare ALPHA_"<<code<<"_XMin = "<<xmin<<endl;
outputfile<<"#declare ALPHA_"<<code<<"_YMin = "<<ymin<<endl;
outputfile<<"#declare ALPHA_"<<code<<"_ZMin = "<<backDepth<<endl;
outputfile<<"#declare ALPHA_"<<code<<"_XMax = "<<xmax<<endl;
outputfile<<"#declare ALPHA_"<<code<<"_YMax = "<<ymax<<endl;
outputfile<<"#declare ALPHA_"<<code<<"_ZMax = "<<frontDepth<<endl;
outputfile<<endl;
outputfile<<"#declare ALPHA_"<<code<<"_Width = "<<(xmax-xmin)<<endl;
outputfile<<"#declare ALPHA_"<<code<<"_Height= "<<(ymax-ymin)<<endl;
outputfile<<"#declare ALPHA_"<<code<<"_Depth = "<<(frontDepth-backDepth)<<endl;
outputfile<<endl;
outputfile<<"#declare ALPHA_"<<code<<" ="<<endl;
outputfile<<" union {"<<endl;
}
else
{
outputfile<<"#declare "<<objName<<"_XMin = "<<xmin<<endl;
outputfile<<"#declare "<<objName<<"_YMin = "<<ymin<<endl;
outputfile<<"#declare "<<objName<<"_ZMin = "<<backDepth<<endl;
outputfile<<"#declare "<<objName<<"_XMax = "<<xmax<<endl;
outputfile<<"#declare "<<objName<<"_YMax = "<<ymax<<endl;
outputfile<<"#declare "<<objName<<"_ZMax = "<<frontDepth<<endl;
outputfile<<endl;
outputfile<<"#declare "<<objName<<"_Width = "<<(xmax-xmin)<<endl;
outputfile<<"#declare "<<objName<<"_Height = "<<(ymax-ymin)<<endl;
outputfile<<"#declare "<<objName<<"_Depth = "<<(frontDepth-backDepth)<<endl;
outputfile<<endl;
outputfile<<"#declare "<<objName<<" = "<<endl;
outputfile<<" union {"<<endl;
}
}
faceTriList.gotoFirst();
for (j=0;j<faceTriList.Count();j++)
{
faceTriList.Current()->v1.z=frontDepth;
faceTriList.Current()->v2.z=frontDepth;
faceTriList.Current()->v3.z=frontDepth;
outputfile<<" ";
if (format==RAW)
faceTriList.Current()->Output(outputfile,format);
else
faceTriList.Current()->Output(outputfile,POV_FLAT);
outputfile<<endl;
faceTriList.gotoNext();
}
faceTriList.gotoFirst();
for (j=0;j<faceTriList.Count();j++)
{
faceTriList.Current()->v1.z=backDepth;
faceTriList.Current()->v2.z=backDepth;
faceTriList.Current()->v3.z=backDepth;
faceTriList.Current()->n1= -faceTriList.Current()->n1;
faceTriList.Current()->n2= -faceTriList.Current()->n2;
faceTriList.Current()->n3= -faceTriList.Current()->n3;
outputfile<<" ";
if (format==RAW)
faceTriList.Current()->Output(outputfile,format);
else
faceTriList.Current()->Output(outputfile,POV_FLAT);
outputfile<<endl;
faceTriList.gotoNext();
}
faceTriList.Empty();
edgeTriList.gotoFirst();
for(j=0;j<edgeTriList.Count();j++)
{
outputfile<<" ";
edgeTriList.Current()->Output(outputfile,format);
outputfile<<endl;
edgeTriList.gotoNext();
}
edgeTriList.Empty();
/*
if (effects==BEVELED)
{
bevelTriList.gotoFirst();
for (j=0;j<bevelTriList.Count();j++)
{
outputfile<<" ";
bevelTriList.Current()->Output(outputfile);
outputfile<<endl;
bevelTriList.gotoNext();
}
bevelTriList.Empty();
}
*/
if (format==POV_SMOOTH || format==POV_FLAT)
{
outputfile<<" }"<<endl;
outputfile<<endl;
}
outputfile<<endl;
cout<<"Done."<<endl;
}
int main(int argc, char* argv[])
{
ULONG code;
ULONG i;
char switchChar;
CHAR fontFileName[255];
CHARPTR objName = NULL;
char outputFileName[255];
// CHAR* fontFileName = new CHAR[255];
double frontDepth = 0.1;
double backDepth = 0.0;
double shrinkFactor = 0.0;
ULONG threshold = 20;
double angleThreshold = threshold*PI/180;
ULONG resolution = 3;
USHORT format = POV_FLAT;
BOOLEAN resolutionSpecified=FALSE;
BOOLEAN codeSpecified = FALSE;
BOOLEAN objectNameSpecified = FALSE;
BOOLEAN fontFileSpecified = FALSE;
BOOLEAN outputFileSpecified = FALSE;
BOOLEAN depthSpecified = FALSE;
BOOLEAN angleThresholdSpecified = FALSE;
if (argc==1)
{
cout<<endl<<" ERROR: Nothing to do."<<endl;
cout<<endl;
PrintOptions();
exit(1);
}
for (i=1;i<argc;i++)
{
if (strlen(argv[i])<3) continue;
if (argv[i][0]!='/')
{
cout<<endl<<" ERROR: Illegal switch -- '"<<argv[i]<<"'"<<endl;
exit(1);
}
switchChar = argv[i][1];
switch (switchChar)
{
case 'f': switch((CHAR)(argv[i][2]))
{
case 'r': format=RAW;
break;
case 's': format=POV_SMOOTH;
break;
default: cout<<endl<<" ERROR: Illegal switch -- '/f"
<<((CHAR)(argv[i][2]))<<"'."<<endl;
break;
}
break;
case 't': sscanf(argv[i]+2,"%d",&threshold);
angleThresholdSpecified=TRUE;
break;
case 'r': sscanf(argv[i]+2,"%d",&resolution);
resolutionSpecified=TRUE;
break;
case 'c': sscanf(argv[i]+2,"%d",&code);
codeSpecified=TRUE;
break;
case 'n': if (objectNameSpecified==FALSE)
objName = new CHAR[255];
strcpy((char*)objName,argv[i]+2);
objectNameSpecified=TRUE;
break;
case 'i': strcpy((char*)fontFileName,argv[i]+2);
fontFileSpecified=TRUE;
break;
case 'o': strcpy(outputFileName,argv[i]+2);
outputFileSpecified=TRUE;
break;
case 'd': sscanf(argv[i]+2,"%5lf",&frontDepth);
depthSpecified=TRUE;
break;
default: cout<<endl<<" ERROR: Illegal switch -- '"<<argv[i]<<"'"<<endl;
exit(1);
break;
}
}
if (fontFileSpecified==FALSE)
{
cout<<endl<<" ERROR: No font file specified."<<endl;
exit(1);
}
if (outputFileSpecified==FALSE)
{
cout<<endl<<" ERROR: No output file specified."<<endl;
exit(1);
}
if (codeSpecified==FALSE)
{
cout<<endl<<" ERROR: No character code specified."<<endl;
exit(1);
}
if (angleThresholdSpecified==TRUE)
{
angleThreshold = threshold*PI/180;
}
TTFont UserFont(fontFileName);
ofstream outputfile(outputFileName);
cout<<endl;
cout<<"Font: "<<UserFont.FullName()<<endl;
cout<<"Curve Resolution: "<<resolution;
if (resolutionSpecified)
cout<<endl;
else
cout<<" (default)"<<endl;
/*
if (effects==BEVELED)
cout<<"Shrink Factor: "<<shrinkFactor<<endl;
*/
cout<<"Character Code: "<<code;
if (codeSpecified)
cout<<endl;
else
cout<<" (default)"<<endl;
cout<<"Character: "<<(char)code<<endl;
cout<<"Depth: "<<frontDepth;
if(depthSpecified)
cout<<endl;
else
cout<<" (default)"<<endl;
if (format == POV_SMOOTH)
cout<<"Generating Smooth Triangles."<<endl;
else if (format == RAW)
cout<<"Generating RAW Output."<<endl;
cout<<"Output File: "<<outputFileName<<endl;
cout<<"Angle Threshold: "<<threshold<<" Degrees, "<<angleThreshold<<" Radians."<<endl;
cout<<endl;
OutputGlyph(outputfile, UserFont, objName, code, format, resolution, frontDepth, backDepth,
shrinkFactor,shrinkFactor,angleThreshold);
return 0;
}